/**
 * Copyright (c) 2012
 */
package com.bolt.support.spring.jpa.filter;


import com.bolt.common.collection.CollectionUtil;
import com.bolt.common.collection.IteratorUtil;
import org.springframework.data.domain.Sort;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;


public class GroupPropertyFilter {

    public static final String GROUP_OPERATION_AND = "and";
    public static final String GROUP_OPERATION_OR = "or";


    /**
     * 组合类型:AND/OR
     */
    private String groupType = GROUP_OPERATION_AND;

    /**
     * 组合条件列表
     */
    private List <PropertyFilter> filters = new ArrayList();

    /**
     * 强制追加AND条件列表
     */
    private List <PropertyFilter> forceAndFilters = new ArrayList();

    /**
     * 组合条件组
     */
    private List <GroupPropertyFilter> groups = new ArrayList();

    private  Sort sort;

    public List <GroupPropertyFilter> getGroups() {
        return groups;
    }

    public void setGroups(List <GroupPropertyFilter> groups) {
        this.groups = groups;
    }

    public String getGroupType() {
        return groupType;
    }

    public void setGroupType(String groupType) {
        this.groupType = groupType;
    }

    public List <PropertyFilter> getFilters() {
        return filters;
    }

    public void setFilters(List <PropertyFilter> filters) {
        this.filters = filters;
    }

    public List <PropertyFilter> getForceAndFilters() {
        return forceAndFilters;
    }

    public GroupPropertyFilter() {
    }

    public GroupPropertyFilter(String groupType) {
        this.groupType = groupType;
    }

    public GroupPropertyFilter append(GroupPropertyFilter... groups) {
        this.groups.addAll(CollectionUtil.newArrayList(groups));
        return this;
    }

    public GroupPropertyFilter append(PropertyFilter... filters) {
        if (IteratorUtil.isNotEmpty(this.groups)) {
            GroupPropertyFilter filter = this.groups.get(this.groups.size() - 1);
            filter.append(filters);
        } else {
            this.filters.addAll(CollectionUtil.newArrayList(filters));
        }
        return this;
    }

    public PropertyFilter getLastFilter() {
        int size = groups.size();
        GroupPropertyFilter last = groups.get(size - 1);
        if (IteratorUtil.isNotEmpty(last.getFilters())) {
            int max = last.getFilters().size();
            return last.getFilters().get(max - 1);
        }
        return null;
    }

    public GroupPropertyFilter forceAnd(PropertyFilter... filters) {
        this.forceAndFilters.addAll(CollectionUtil.newArrayList(filters));
        return this;
    }

    public boolean isEmpty() {
        return CollectionUtil.isEmpty(groups) && CollectionUtil.isEmpty(filters);
    }

    public static GroupPropertyFilter buildDefaultAndGroupFilter(PropertyFilter... filters) {
        GroupPropertyFilter dpf = new GroupPropertyFilter(GROUP_OPERATION_AND);
        if (filters != null && filters.length > 0) {
            dpf.setFilters(CollectionUtil.newArrayList(filters));
        }
        return dpf;
    }

    public static GroupPropertyFilter buildDefaultOrGroupFilter(PropertyFilter... filters) {
        GroupPropertyFilter dpf = new GroupPropertyFilter(GROUP_OPERATION_OR);
        if (filters != null && filters.length > 0) {
            dpf.setFilters(CollectionUtil.newArrayList(filters));
        }
        return dpf;
    }

    public static GroupPropertyFilter buildFromHttpRequest(Class <?> entityClass, HttpServletRequest request) {
        try {
            GroupPropertyFilter groupPropertyFilter = new GroupPropertyFilter();
            List <PropertyFilter> filters = PropertyFilter.buildFiltersFromHttpRequest(entityClass, request);
            if (CollectionUtil.isNotEmpty(filters)) {
                GroupPropertyFilter comboGroupPropertyFilter = new GroupPropertyFilter();
                comboGroupPropertyFilter.setGroupType(GROUP_OPERATION_AND);
                GroupPropertyFilter normalGroupPropertyFilter = new GroupPropertyFilter();
                normalGroupPropertyFilter.setGroupType(GROUP_OPERATION_AND);
                normalGroupPropertyFilter.setFilters(filters);
                comboGroupPropertyFilter.getGroups().add(normalGroupPropertyFilter);
                comboGroupPropertyFilter.getGroups().add(groupPropertyFilter);
                return comboGroupPropertyFilter;
            }
            return groupPropertyFilter;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public Sort getSort() {
        return sort;
    }

    public void setSort(Sort sort) {
        this.sort = sort;
    }


}








